package com.cloud.util;

import org.codehaus.jackson.map.DeserializationConfig;
import org.codehaus.jackson.map.ObjectMapper;
import org.codehaus.jackson.map.SerializationConfig;
import org.codehaus.jackson.map.annotate.JsonFilter;
import org.codehaus.jackson.map.ser.impl.SimpleBeanPropertyFilter;
import org.codehaus.jackson.map.ser.impl.SimpleFilterProvider;
import org.codehaus.jackson.type.TypeReference;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.core.annotation.AnnotationUtils;
import org.springframework.stereotype.Component;

import java.io.IOException;
import java.text.SimpleDateFormat;
/**
 * @Author wangjian (jian.wang@bertelsmann.com.cn)
 * @Date 2017/1/16 15:20
 */
@Component
public class JsonUtils implements InitializingBean {
    private ObjectMapper objectMapper = null;

    @Override
    public void afterPropertiesSet() throws Exception {
        objectMapper = new ObjectMapper();
        objectMapper.setDateFormat(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"));
        objectMapper.disable(DeserializationConfig.Feature.FAIL_ON_UNKNOWN_PROPERTIES);
        objectMapper.configure(SerializationConfig.Feature.FAIL_ON_EMPTY_BEANS, false);
        objectMapper.setFilters(new SimpleFilterProvider().setFailOnUnknownId(false));
    }

    /**
     *
     * @param object
     * @return
     * @throws Exception
     */
    public String toJsonString(Object object) throws IOException {
        return objectMapper.writeValueAsString(object);
    }

    /**
     *
     * @param object
     * @param properties
     * @return
     * @throws Exception
     */
    public String toJsonString(Object object, String... properties) throws IOException {
        return objectMapper.writer(new SimpleFilterProvider().addFilter(AnnotationUtils.getValue(AnnotationUtils.findAnnotation(object.getClass(), JsonFilter.class)).toString(), SimpleBeanPropertyFilter.filterOutAllExcept(properties))).writeValueAsString(object);
    }

    /**
     *
     * @param json
     * @param clazz
     * @param <T>
     * @return
     * @throws Exception
     */
    public <T> T parse(String json, Class<T> clazz) throws IOException {
        if (json == null || json.length() == 0) {
            return null;
        }
        return objectMapper.readValue(json, clazz);
    }

    /**
     *
     * @param json
     * @param typeReference 参数 TypeReference 示例：new TypeReference<Map<String,User>>() {}
     * @param <T>
     * @return
     * @throws Exception
     */
    public <T> T parseCollection(String json, TypeReference typeReference) throws IOException {
        if (json == null || json.length() == 0) {
            return null;
        }
        return objectMapper.readValue(json,typeReference);
    }
}
